baselib.report(0x00, "TD4.5.1 beginning.")

--[[Conditions:
1. CVS emulates a SNK receptacle connector [TD.4.5.1.C.4]
2. CVS emulates USB PD 2.0 5A Active Cable [TD.4.5.1.C.1]
3. CVS emulates USB PD 3.0 5A Active Cable [TD.4.5.1.C.2]
4. CVS emulates USB4 re-driver cable (ID Header Product Type = Passive, Cable VDO indicate Vconn required, TBT3 SVID / Mode supported and mode indicates Active Cable) [TD.4.5.1.C.3]
]]

-- 下面是初始化操作:
busilib.SetOrientation(1)                      -- 设置USB的CC线,另一根则为Vconn线(这里设置CC1)
busilib.SetRpValue(1, 0)                       -- 设置USB Source用于标识输出电流能力的电阻值,第二个参数写0代表500mA
busilib.setUsbCcs(CCS.Disabled)                -- 设置CVS为Disabled.SNK      
busilib.setUsbRole(ROLE.SNK)
local circ_times = 0                           -- 标识循环次数
--[[第一步:If VIF field Captive_Cable is set to YES, CVS emulates a receptacle as per condition 1 in Section D above, otherwise CVS emulates an Active cable as per condition 2
如果VIF字段 Captive_Cable 设置为 YES，CVS 模拟一个插座连接器(Conditions 1)。否则，CVS 模拟一个主动电缆(Conditions 2)，
然后模拟Conditions 3、4]]
if Captive_Cable then
    busilib.setUsbCable(1, 0)                  -- CVS是否模拟主动电缆，第二个参数写0代表不模拟主动电缆
    tcpclib.SetPermission(1, 0)                -- 需要设置的权限，第二个参数由四位二进制组成。最高位至最低位分别为Vbus、Vconn、CC1、CC2的权限
else
    circ_times = 1                             -- 如果不是Captive_Cable，跳过一次循环
end

:: circ_start ::
if circ_times ~= 0 then
    busilib.SetSwitchState(SW.EMAK123_PWR, 1)  -- 打开三个 E-Marker 芯片的电源
end
-- 根据循环次数判断执行到哪个Conditions，然后打开对应开关
if circ_times == 1 then
    busilib.SetSwitchState(SW.EMAK1_CC1, 1)
elseif circ_times == 2 then
    busilib.SetSwitchState(SW.EMAK2_CC2, 1)
elseif circ_times == 3 then
    busilib.SetSwitchState(SW.EMAK3_CC3, 1)
end

--[[ 第二步:If VIF field Type_C_Sources_Vconn is NO, CVS verifies that the PUT does not source Vconn for the remainder of the test. [TD.4.5.1.V.1]
如果 VIF 字段 Type_C_Sources_Vconn 为 NO，CVS 验证 PUT 在测试的剩余部分不提供 Vconn [TD.4.5.1.V.1] ]]
if not Type_C_Sources_Vconn then
    -- 牵扯问题：需要断开 CVS 提供的 VConn 才能测量待测物的 VConn 情况
    -- 如果 CVS 不提供 VConn、而是仅由待测物提供则无此问题（VConn 是否存在两侧都要提供的情况？）
    local Vvconn = busilib.GetADC(ADC.CC2, 4)
    baselib.report(0x00, "Vvconn is " .. Vvconn .. "mV.")
    if Vvconn < 2750 then   -- 2750 待定（群内 Table 3）
        baselib.report(0x00, "TD4.5.1.V.1 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.1 fail.")
    end
end

-- 第三步:CVS 转换到 Unattached.SNK 状态
busilib.setUsbCcs(CCS.Unattached)
-- 第四步:等待 5ms
baselib.delay(5)
-- 第五步:对于一个PUT_R,PUT_R在VIF中提供
if PUT_R then
    -- 5.a步:CVS terminates one CC pin with Ra for the duration of the test
    busilib.SetSwitchState(SW.CC2_RA, 1)       -- 将CC2_RA开关打开
    -- 5.b步:CVS verifies PUT has transitioned to Unattached.SRC(PUT applies Rp simultaneously on both CC pins [TD.4.5.1.V.2])
    -- CVS 验证 PUT 已转换到 Unattached.SRC 状态：PUT 同时在两个 CC 引脚上应用 Rp
    local VCC1 = busilib.GetADC(ADC.CC1, 4)
    local VCC2 = busilib.GetADC(ADC.CC2, 4)
    baselib.report(0x00, "CC1 is " .. VCC1 .. "mV, and CC2 is " .. VCC2 .. "mV.")
    if VCC1 > 1650 and VCC2 > 200 then
        baselib.report(0x00, "TD4.5.1.V.2 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.2 fail.")
    end
    -- 5.c步:CVS 等待 80ms
    baselib.delay(80)
    -- 5.d步:CVS verifies PUT has applied Rp since step b [TD.4.5.1.V.3]
    -- 这里重复了 5.b 步的操作
    VCC1 = busilib.GetADC(ADC.CC1, 4)
    VCC2 = busilib.GetADC(ADC.CC2, 4)
    baselib.report(0x00, "CC1 is " .. VCC1 .. "mV, and CC2 is " .. VCC2 .. "mV.")
    if VCC1 > 200 and VCC2 > 200 then
        baselib.report(0x00, "TD4.5.1.V.3 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.3 fail.")
    end
    -- 5.e步:CVS transitions to Disabled except for one CC maintaining Ra
    -- CVS 转换到 Disabled 状态，CC2保持Ra
    busilib.setUsbCcs(CCS.Disabled)
    busilib.SetSwitchState(SW.CC2_RA, 1)
    -- 5.f步:CVS verifies PUT transitions to Unattached.SNK [TD.4.5.1.V.4]
    -- CVS 验证 PUT 转换到 Unattached.SNK 状态
    VCC1 = busilib.GetADC(ADC.CC1, 4)
    baselib.report(0x00, "CC1 is " .. VCC1 .. "mV.")
    if VCC1 < 1600 then
        baselib.report(0x00, "TD4.5.1.V.4 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.4 fail.")
    end
    -- 5.g步:等待 750ms
    baselib.delay(750)
    -- 5.h步:CVS 转换到 Unattached.SNK 状态
    busilib.setUsbCcs(CCS.Unattached)
end
-- 第6步:6.a:PUT attaches Rp within max dcSRC.DRP x max tDRP [TD.4.5.1.V.5]
-- 6.a步:PUT 在 max dcSRC.DRP × max tDRP 内施加 Rp
baselib.delay(70)                     -- 等待max dcSRC.DRP x max tDRP  
VCC1 = busilib.GetADC(ADC.CC1, 4)
VCC2 = busilib.GetADC(ADC.CC2, 4)
baselib.report(0x00, "CC1 is " .. VCC1 .. "mV, and CC2 is " .. VCC2 .. "mV.")
if VCC1 > 200 and VCC2 > 200 then
    baselib.report(0x00, "TD4.5.1.V.5 pass.")
else
    baselib.report(0x00, "TD4.5.1.V.5 fail.")
end
-- 6.b步:After tCCDebounce, PUT supplies VBUS within tVBUSON [TD.4.5.1.V.6]
-- 在 tCCDebounce 之后，PUT 在 tVBUSON 内提供 VBUS
baselib.delay(200+275)               -- tCCDebounce:200ms+tVBUSON:275ms
if cstmlib.VBusVerified(1) then 
    baselib.report(0x00, "TD4.5.1.V.6 pass.")
else
    baselib.report(0x00, "TD4.5.1.V.6 fail.")
end
-- 6.c步:PUT sources current at the level it advertises with Type-C Current [TD.4.5.1.V.7]
-- PUT 提供的电流与其通过 Type-C 电流广告的电流水平是否一致
busilib.SetDAC(DAC.VBUS_EL_I, 10*Src_PDO_Max_Current)    -- 设置VBUS电子负载的电流，大小和VIF相应字段有关（目前以为是Src_PDO_Max_Current）
local VBus = busilib.GetADC(ADC.VBUS, 4)                 -- 设置电子负载电流后，判断电源是否正常
baselib.report(0x00, "VBus is " .. VBus .. "mV.")
if VBus > 3670 then -- Spec P146?
    baselib.report(0x00, "TD4.5.1.V.7 pass.")
else
    baselib.report(0x00, "TD4.5.1.V.7 fail.")
end
busilib.SetDAC(DAC.VBUS_EL_I, 0)                         -- 关闭电子负载
-- 第七步:初始化 Vconn_tested 变量，用于标记是否已测试 Vconn 功能
local Vconn_tested = false
-- 第八步:If PUT supports USB PD:
if PUT_supports_PD then
    --[[ 8.a步:CVS verifies that:
    1、PUT stabilizes VBUS before initiating USB PD communications[TD.4.5.1.V.8]    PUT在启动USB PD通信之前稳定 VBUS
    2、CVS and PUT negotiate a contract. [TD.4.5.1.V.9]     CVS 和 PUT 协商一个合约  ]]
    VBus = busilib.GetADC(ADC.VBUS, 4)
    baselib.report(0x00, "VBus is " .. VBus .. "mV.")
    if VBus > 3670 then -- Spec P146?
        baselib.report(0x00, "TD4.5.1.V.8 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.8 fail.")
    end
    -- 这里是a.2步
    tcpclib.SetPermission(1, 2)
    PN_result = tcpclib.PresetPowerNegotiation(1, 500)  -- timeout is 500ms
    if PN_result == LuaOk then
        baselib.report(0x00, "TD4.5.1.V.9 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.9 fail.")
    end

    --[[If PUT source capabilities include a Max Current > 3 A:          (如果 PUT 的源端能力包括 最大电流 > 3 A)
    i. CVS verifies that for a PUT_R, it supplies Vconn within tVconnON [TD.4.5.1.V.10]     (CVS 验证PUT_R在 tVconnON 内提供 Vconn)
    ii. Vconn_tested = true]]
    if PUT_SOURCE_CAP_HIGER_3A then                      -- 这里直接取VIF字段PUT_SOURCE_CAP_HIGER_3A
        -- 没判断 Type_C_Sources_Vconn 字段？Source 不是必须提供 VConn？
        -- 测量待测物应加载了 VConn
        baselib.delay(2)                                 -- 等待tVconnON（2ms）
        Vvconn = busilib.GetADC(ADC.CC2, 4)
        baselib.report(0x00, "Vvconn is " .. Vvconn .. "mV.")
        if Vvconn > 2750 then   -- 2750 待定（群内 Table 3）
            baselib.report(0x00, "TD4.3.1.V.1 pass.")
        else
            baselib.report(0x00, "TD4.3.1.V.1 fail.")
        end
        Vconn_tested = true
    end
    --这一步和第二步有一样的问题
end

-- 第九步:PUT supports USB 3.1 DFP:
-- TBD

-- 第十步:If the PUT is a PUT_V and not Vconn_tested:a. CVS verifies that for a PUT_R, it supplies Vconn within tVconnON [TD.4.5.1.V.19]
-- 如果 PUT 是 PUT_V 且未测试 Vconn. CVS 验证对于 PUT_R，它在 tVconnON 内提供 Vconn
if PUT_V and not Vconn_tested then
    baselib.delay(2)                                       -- 等待tVconnON（2ms）
    Vvconn = busilib.GetADC(ADC.CC2, 4)
    baselib.report(0x00, "Vvconn is " .. Vvconn .. "mV.")
    if Vvconn > 2750 then  
        baselib.report(0x00, "TD4.5.1.V.19 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.19 fail.")
    end
end
-- 第十一步:CVS 转换到 Disabled 状态
busilib.setUsbCcs(CCS.Disabled)
-- 第十二步:CVS verifies that PUT transitions to Unattached.SNK within tSRCDisconnect.
-- CVS 验证 PUT 在 tSRCDisconnect 内转换到 Unattached.SNK 状态

-- 12.a步
-- TBD

-- 12.b步:PUT_V removes Vconn within tVconnOFF. [TD.4.5.1.V.16]
-- PUT_V 在 tVconnOFF 内移除 Vconn
baselib.delay(35)           -- 等待tVconnOFF（35ms）
if PUT_V then
    Vvconn = busilib.GetADC(ADC.CC2, 4)
    baselib.report(0x00, "Vvconn is " .. Vvconn .. "mV.")
    if Vvconn < 2750 then   -- 2750 待定（群内 Table 3）
        baselib.report(0x00, "TD4.5.1.V.16 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.16 fail.")
    end
end
-- 12.c步:PUT removes VBUS within tVBUSOFF [TD.4.5.1.V.17]
-- PUT 在 tVBUSOFF 内移除 VBUS
baselib.delay(650-35)       -- 这里是650（tVBUSOFF）-35（tVconnOFF）(因为12.b步已经等待了35ms)
VBus = busilib.GetADC(ADC.VBUS, 4)
baselib.report(0x00, "VBus is " .. VBus .. "mV.")
if VBus < 3670 then -- Spec P146?
    baselib.report(0x00, "TD4.5.1.V.17 pass.")
else
    baselib.report(0x00, "TD4.5.1.V.17 fail.")
end
--[[12.d步:PUT presents Rd terminations on its through CC pin [TD.4.5.1.V.18] For a PUT_R, verify both CC pins terminated to Rd
PUT 在其直通 CC 引脚上提供 Rd 终端 ,对于 PUT_R，验证两个 CC 引脚都终止为 Rd]]
VCC1 = busilib.GetADC(ADC.CC1, 4)
VCC2 = busilib.GetADC(ADC.CC2, 4)
baselib.report(0x00, "CC1 is " .. VCC1 .. "mV, and CC2 is " .. VCC2 .. "mV.")
if PUT_R then
    if VCC1 < 200 and VCC2 < 200 then
        baselib.report(0x00, "TD4.5.1.V.18 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.18 fail.")
    end
else
    if VCC1 < 200 then
        baselib.report(0x00, "TD4.5.1.V.18 pass.")
    else
        baselib.report(0x00, "TD4.5.1.V.18 fail.")
    end
end
-- 关闭所有开关
busilib.SetSwitchState(SW.EMAK1_CC1, 0)
busilib.SetSwitchState(SW.EMAK2_CC2, 0)
busilib.SetSwitchState(SW.EMAK3_CC3, 0)
busilib.SetSwitchState(SW.EMAK123_PWR, 0)
-- 第十三步:If VIF field Captive_Cable is NO, the CVS continues the test with step 2, using the next Condition from section D above
-- 这一步就是循环执行剩下的Condition
if not Captive_Cable and circ_times < 3 then
    circ_times = circ_times + 1
    goto circ_start
end

baselib.report(0x00, "Demo is done here.")
baselib.report(0x07, "\x04")
